<template>
  <div class="ai-chat-component">
    <!-- 对话内容区域：循环渲染所有历史对话记录 -->
    <div class="chat-container" ref="messagesContainer">
      <!-- 每条对话记录：包含「用户问题 + AI思考 + AI回答」 -->
      <div v-for="(record, index) in chatRecords" :key="index" class="chat-record">
        <!-- 1. 用户问题区域（新增：显示当前轮次用户输入） -->
        <div class="user-question-container">
          <h3>你</h3>
          <div class="user-question-content">
            <p>{{ record.userQuestion }}</p>
          </div>
        </div>

        <!-- 2. AI 思考过程区域（绑定当前记录的折叠/内容状态） -->
        <div
          class="thoughts-container"
          :class="{ collapsed: record.isThoughtsCollapsed }"
          v-if="record.aiThoughts || record.isGenerating"
        >
          <div class="thoughts-header" @click="() => toggleThoughtsCollapse(index)">
            <h3>AI 思考过程</h3>
            <span class="toggle-icon">{{ record.isThoughtsCollapsed ? '+' : '-' }}</span>
          </div>
          <div class="thoughts-content" v-if="!record.isThoughtsCollapsed">
            <p>{{ record.aiThoughts || (record.isGenerating ? 'AI 正在梳理思路...' : '') }}</p>
          </div>
        </div>

        <!-- 3. AI 回答区域（绑定当前记录的生成/内容状态） -->
        <div class="answer-container" v-if="record.aiAnswer || record.isGenerating">
          <h3>AI 回答</h3>
          <div class="answer-content">
            <MarkdownRenderer :content="record.aiAnswer" />
            <!-- 加载状态：仅当前记录生成中时显示 -->
            <div v-if="record.isGenerating" class="loading-indicator">
              <a-spin size="small" />
              <span>AI 正在生成回答...</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 输入区域：禁用条件改为「当前有对话正在生成」 -->
    <div class="input-area">
      <a-select
        v-model:value="selectValue"
        mode="multiple"
        style="width: 100%"
        placeholder="请选择要提供给大模型的数据"
        :options="options"
        @change="handleChange"
        @deselect="handleDeselect"
      ></a-select>
      <a-textarea
        v-model:value="userInput"
        placeholder="请输入您的问题..."
        :rows="3"
        :maxlength="1000"
        @keydown.enter.prevent="sendMessage"
        :disabled="isCurrentGenerating"
      />
      <div class="input-actions">
        <a-button
          type="primary"
          @click="sendMessage"
          :loading="isCurrentGenerating"
          :disabled="!userInput.trim() || isCurrentGenerating"
        >
          <template #icon>
            <SendOutlined />
          </template>
          发送
        </a-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onUnmounted, computed, onMounted, watch, reactive } from 'vue'
import { message, type SelectProps } from 'ant-design-vue'
import MarkdownRenderer from '@/components/MarkdownRenderer.vue'
import { SendOutlined } from '@ant-design/icons-vue'
import request from '@/request'
import { historyChat } from '@/api/aiChatController.ts'
import { useEnvironmentDataStore } from '@/stores/useEnvironmentDataStore.ts'

// ========================== 1. 核心：定义对话记录结构与数组 ==========================
// 单条对话记录的类型（包含用户问题、AI思考、AI回答、状态）
interface ChatRecord {
  userQuestion: string // 用户的问题
  aiThoughts: string // AI的思考过程
  aiAnswer: string // AI的最终回答
  isGenerating: boolean // 当前记录是否正在生成中
  isThoughtsCollapsed: boolean // 思考过程是否折叠
  isThinkingCompleted: boolean // 思考过程是否完成
}

// 定义属性
interface Props {
  chatId: string
}

// 子组件定义 props
const props = defineProps({
  chatId: {
    type: String,
    required: true,
  },
})

// 存储所有历史对话记录（核心：替代原单条状态，实现记录叠加）
const chatRecords = ref<ChatRecord[]>([])
const environmentDataStore = useEnvironmentDataStore()
const selectValue = ref<string[]>([])
const envData = ref<API.EnvironmentData>({
  dataTimestamp: environmentDataStore.getDataTimestamp(),
  indoorTemperature: [],
  outdoorTemperature: [],
  moisture: [],
  soilFertilizerConcentration: [],
  soilPh: [],
  illumination: [],
  conductivity: [],
  potassium: [],
  nitrogen: [],
  phosphorus: [],
})
const options = ref<SelectProps['options']>([
  { value: 'indoorTemperature', label: '室内温度' },
  { value: 'outdoorTemperature', label: '室外温度' },
  { value: 'moisture', label: '含水量' },
  { value: 'soilFertilizerConcentration', label: '土壤肥力浓度' },
  { value: 'soilPh', label: '土壤PH值' },
  { value: 'illumination', label: '光照强度' },
  { value: 'conductivity', label: '电导率' },
  { value: 'potassium', label: '钾含量' },
  { value: 'nitrogen', label: '氮含量' },
  { value: 'phosphorus', label: '磷含量' },
])
const handleChange = (value: string[]) => {
  console.log('selected', value[value.length - 1])
  switch (value[value.length - 1]) {
    case 'indoorTemperature':
      envData.value.indoorTemperature = environmentDataStore.getIndoorTemperature()
      break
    case 'outdoorTemperature':
      envData.value.outdoorTemperature = environmentDataStore.getOutdoorTemperature()
      break
    case 'moisture':
      envData.value.moisture = environmentDataStore.getMoisture()
      break
    case 'soilFertilizerConcentration':
      envData.value.soilFertilizerConcentration =
        environmentDataStore.getSoilFertilizerConcentration()
      break
    case 'soilPh':
      envData.value.soilPh = environmentDataStore.getSoilPh()
      break
    case 'illumination':
      envData.value.illumination = environmentDataStore.getIllumination()
      break
    case 'conductivity':
      envData.value.conductivity = environmentDataStore.getConductivity()
      break
    case 'potassium':
      envData.value.potassium = environmentDataStore.getPotassium()
      break
    case 'nitrogen':
      envData.value.nitrogen = environmentDataStore.getNitrogen()
      break
    case 'phosphorus':
      envData.value.phosphorus = environmentDataStore.getPhosphorus()
      break
    default:
      break
  }
  console.log('now: ', envData.value)
}
const handleDeselect = (value: string) => {
  console.log('deselected', value)
  switch (value) {
    case 'indoorTemperature':
      envData.value.indoorTemperature = []
      break
    case 'outdoorTemperature':
      envData.value.outdoorTemperature = []
      break
    case 'moisture':
      envData.value.moisture = []
      break
    case 'soilFertilizerConcentration':
      envData.value.soilFertilizerConcentration = []
      break
    case 'soilPh':
      envData.value.soilPh = []
      break
    case 'illumination':
      envData.value.illumination = []
      break
    case 'conductivity':
      envData.value.conductivity = []
      break
    case 'potassium':
      envData.value.potassium = []
      break
    case 'nitrogen':
      envData.value.nitrogen = []
      break
    case 'phosphorus':
      envData.value.phosphorus = []
      break
    default:
      break
  }
  console.log('now: ', envData.value)
}

// ========================== 2. 基础状态与工具变量 ==========================
const userInput = ref('') // 用户输入框内容
const messagesContainer = ref<HTMLElement>() // 对话容器（用于滚动到底部）
let eventSource: EventSource | null = null // SSE连接实例
let lastReceivedTime = 0 // 最后一次接收SSE数据的时间
let isExpectedClose = false // 是否为预期的SSE连接关闭

// 计算属性：当前是否有对话正在生成（避免重复发送）
const isCurrentGenerating = computed(() => {
  return chatRecords.value.length > 0 && chatRecords.value.at(-1)?.isGenerating
})

// ========================== 3. 发送消息逻辑（核心修改） ==========================
const sendMessage = async () => {
  const userQuestion = userInput.value.trim()
  // 校验：无输入或当前有对话生成中，不允许发送
  if (!userQuestion || isCurrentGenerating.value) return

  // 关键：新增一条对话记录到历史数组末尾（当前轮对话）
  chatRecords.value.push({
    userQuestion, // 存入当前用户问题
    aiThoughts: '', // 初始为空，后续通过SSE累加
    aiAnswer: '', // 初始为空，后续通过SSE累加
    isGenerating: true, // 标记为「正在生成」
    isThoughtsCollapsed: false, // 初始展开思考过程
    isThinkingCompleted: false, // 初始未完成思考
  })

  // 滚动到最新对话
  scrollToBottom()

  // SSE连接初始化（保留原逻辑，仅修改数据写入目标为「当前记录」）
  lastReceivedTime = 0
  isExpectedClose = false
  let streamCompleted = false

  try {
    const baseURL = request.defaults.baseURL || 'http://localhost:8080/api'
    if (props.chatId === null) {
      message.error('获取到chatId异常')
      return
    }
    const params = new URLSearchParams({
      userMessage: userQuestion,
      chatId: props.chatId, // 建议后续改为动态生成的唯一ID（如用户ID+时间戳）
      environmentData: JSON.stringify(envData),
    })
    const url = `${baseURL}/ai/memory/chat?${params}`

    // 创建SSE连接
    eventSource = new EventSource(url, { withCredentials: true })

    // 3.1 处理SSE流数据（写入当前对话记录）
    eventSource.onmessage = (event) => {
      if (streamCompleted) return
      userInput.value = ''
      lastReceivedTime = Date.now()
      try {
        const data = JSON.parse(event.data)
        // 获取当前正在生成的对话记录（数组最后一条）
        const currentRecord = chatRecords.value.at(-1)
        if (currentRecord) {
          processStreamData(currentRecord, data) // 累加思考/回答内容
          scrollToBottom() // 实时滚动到最新内容
        }
      } catch (error) {
        console.error('解析SSE数据失败:', error)
        handleError(new Error('接收数据格式错误'))
      }
    }

    // 3.2 处理SSE完成事件
    eventSource.addEventListener('done', () => {
      if (streamCompleted) return
      isExpectedClose = true
      const currentRecord = chatRecords.value.at(-1)
      if (currentRecord) {
        handleStreamComplete(currentRecord) // 标记生成完成
      }
      streamCompleted = true
      scrollToBottom()
    })

    // 3.3 处理业务错误（如AI生成失败）
    eventSource.addEventListener('business-error', (event: MessageEvent) => {
      if (streamCompleted) return
      try {
        const errorData = JSON.parse(event.data)
        message.error(errorData.message || '生成过程中出现错误')
        const currentRecord = chatRecords.value.at(-1)
        if (currentRecord) {
          currentRecord.aiThoughts = `❌ ${errorData.message || '生成失败'}`
          currentRecord.isGenerating = false // 停止加载状态
        }
      } catch (parseError) {
        console.error('解析错误信息失败:', parseError)
        handleError(new Error('服务器返回错误格式不正确'))
      } finally {
        streamCompleted = true
        cleanupEventSource()
      }
    })

    // 3.4 处理SSE连接错误
    eventSource.onerror = () => {
      if (streamCompleted || !isCurrentGenerating.value) return
      if (eventSource?.readyState === EventSource.CONNECTING) {
        streamCompleted = true
        const currentRecord = chatRecords.value.at(-1)
        if (currentRecord) currentRecord.isGenerating = false
        eventSource.close()
      } else {
        handleError(new Error('SSE连接异常'))
      }
    }
  } catch (error) {
    console.error('创建SSE连接失败:', error)
    const currentRecord = chatRecords.value.at(-1)
    if (currentRecord) currentRecord.isGenerating = false
  }
}

// ========================== 4. 辅助函数（适配对话记录数组） ==========================
/**
 * 处理SSE流数据：累加AI思考过程和回答到当前记录
 */
const processStreamData = (currentRecord: ChatRecord, data: any) => {
  // 累加思考过程
  if (data.output?.thoughts?.[0]?.actionType === 'reasoning' && data.output.thoughts[0].response) {
    currentRecord.aiThoughts += data.output.thoughts[0].response
  }
  // 累加正式回答
  if (data.output?.text) {
    currentRecord.aiAnswer += data.output.text
  }
}

/**
 * 处理SSE流完成：更新当前记录状态
 */
const handleStreamComplete = (currentRecord: ChatRecord) => {
  currentRecord.isGenerating = false // 停止加载
  currentRecord.isThinkingCompleted = true // 标记思考完成
  currentRecord.isThoughtsCollapsed = true // 自动折叠思考过程
}

/**
 * 错误处理：更新当前记录状态并提示
 */
const handleError = (error: Error) => {
  message.error(error.message)
  const currentRecord = chatRecords.value.at(-1)
  if (currentRecord) {
    currentRecord.isGenerating = false
    currentRecord.aiThoughts = `❌ ${error.message}`
  }
  cleanupEventSource()
}

/**
 * 切换思考过程的展开/折叠（按记录索引操作）
 */
const toggleThoughtsCollapse = (index: number) => {
  const record = chatRecords.value[index]
  // 仅思考完成后允许折叠/展开
  if (record && record.isThinkingCompleted) {
    record.isThoughtsCollapsed = !record.isThoughtsCollapsed
  }
}

/**
 * 滚动到最新对话
 */
const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight
  }
}

/**
 * 清理SSE连接
 */
const cleanupEventSource = () => {
  if (eventSource) {
    eventSource.close()
    eventSource = null
  }
}

const fetchChatHistory = async (chatId: string) => {
  try {
    if (chatId === null) return
    const res = await historyChat({ chatId: parseInt(chatId) })
    if (res && res.data && Array.isArray(res.data)) {
      const tempRecords: ChatRecord[] = []
      let userQuestion = ''
      let aiAnswer = ''
      res.data.forEach((item, index) => {
        if (item.role === 'user') {
          userQuestion = item.content
          // 如果是最后一条且是用户消息，或者下一条是 assistant 消息，先暂存用户问题
          if (index === res.data.length - 1 || res.data[index + 1].role === 'assistant') {
            aiAnswer = ''
          }
        } else if (item.role === 'assistant') {
          aiAnswer += item.content
          // 当是 assistant 消息时，且存在用户问题（可能上一条是用户消息），组合成一条 ChatRecord
          if (userQuestion) {
            tempRecords.push({
              userQuestion,
              aiThoughts: '', // 历史记录没有大模型思考内容，设为空
              aiAnswer,
              isGenerating: false,
              isThoughtsCollapsed: false,
              isThinkingCompleted: true,
            })
            userQuestion = '' // 重置用户问题，准备下一轮
            aiAnswer = ''
          }
        }
      })
      chatRecords.value = tempRecords
    }
  } catch (error) {
    console.error('获取历史聊天记录失败:', error)
  }
}

onMounted(() => {
  fetchChatHistory(props.chatId)
})

// 监听 chatId 变化
watch(
  () => props.chatId,
  () => {
    fetchChatHistory(props.chatId)
  },
  { immediate: true }, // 初始值也执行
)

// ========================== 5. 组件卸载时清理资源 ==========================
onUnmounted(() => {
  cleanupEventSource() // 关闭SSE连接，避免内存泄漏
})
</script>

<style scoped>
.ai-chat-component {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 对话容器：固定高度+滚动 */
.chat-container {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 8px; /* 避免滚动条遮挡内容 */
}

/* 单条对话记录：上下间距+分隔线 */
.chat-record {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid #f5f5f5;
}
/* 最后一条记录不需要分隔线 */
.chat-record:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: none;
}

/* ========================== 用户问题样式 ========================== */
.user-question-container {
  border: 1px solid #e8f4ff;
  border-radius: 6px;
}
.user-question-container h3 {
  margin: 0;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 500;
  background-color: #e8f4ff;
  border-bottom: 1px solid #e8f4ff;
  color: #1890ff; /* 蓝色标识用户 */
}
.user-question-content {
  padding: 12px;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  background-color: #f7fbff;
}

/* ========================== AI思考过程样式（保留原逻辑） ========================== */
.thoughts-container {
  border: 1px dashed #e0e0e0;
  border-radius: 6px;
  transition: all 0.3s ease;
}
.thoughts-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  background-color: #f5f7fa;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
}
.toggle-icon {
  font-size: 16px;
  font-weight: bold;
  color: #888;
}
.thoughts-content {
  padding: 12px;
  font-size: 14px;
  line-height: 1.6;
  color: #666;
  background-color: #fafafa;
  border-top: 1px dashed #e0e0e0;
}
.thoughts-container.collapsed .thoughts-content {
  display: none;
}

/* ========================== AI回答样式（保留原逻辑） ========================== */
.answer-container {
  border: 1px solid #e8e8e8;
  border-radius: 6px;
}
.answer-container h3 {
  margin: 0;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 500;
  background-color: #f0f2f5;
  border-bottom: 1px solid #e8e8e8;
}
.answer-content {
  padding: 16px;
  line-height: 1.6;
}

/* ========================== 输入区域样式（保留原逻辑） ========================== */
.input-area {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.input-actions {
  align-self: flex-end;
}
.loading-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #666;
  padding: 8px 0;
}
</style>
